package com.jxtc.enterprise.delivery.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jxtc.enterprise.common.constants.MealTypeEnum;
import com.jxtc.enterprise.common.dto.TodayTaskOrderDetailDTO;
import com.jxtc.enterprise.common.entity.DeliveryTask;
import com.jxtc.enterprise.common.entity.DeliveryTaskStore;
import com.jxtc.enterprise.common.entity.Store;
import com.jxtc.enterprise.common.exception.ModifyFailureException;
import com.jxtc.enterprise.common.mapper.DeliveryTaskMapper;
import com.jxtc.enterprise.common.mapper.DeliveryTaskStoreMapper;
import com.jxtc.enterprise.common.mapper.OrderDetailMapper;
import com.jxtc.enterprise.common.mapper.StoreMapper;
import com.jxtc.enterprise.common.vo.DeliverBoxApiParamVO;
import com.jxtc.enterprise.common.vo.PaginationResponseVO;
import com.jxtc.enterprise.delivery.dto.todayTask.CompanyIdWithMealTypeDTO;
import com.jxtc.enterprise.delivery.dto.todayTask.RiderTodayTaskDTO;
import com.jxtc.enterprise.delivery.dto.todayTask.TodayStoreOrderDTO;
import com.jxtc.enterprise.delivery.vo.todayTask.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class RiderTodayTaskService {

    private final DeliveryTaskMapper deliveryTaskMapper;
    private final DeliveryTaskStoreMapper deliveryTaskStoreMapper;
    private final StoreMapper storeMapper;
    private final OrderDetailMapper orderDetailMapper;

    public PaginationResponseVO<RiderTodayTaskVO> queryTaskByStatus(String riderId, int status, int current, int size) {
        // 获取当天 yyyy-MM-dd 格式日期
        String deliveryDate = getCurrentDate();

        Page<RiderTodayTaskDTO> page = new Page<>(current, size);
        Page<RiderTodayTaskDTO> pageResult = deliveryTaskMapper.pageTodayTask(page, riderId, status, deliveryDate);
        List<String> taskIdList = pageResult.getRecords().stream()
                .map(RiderTodayTaskDTO::getTaskId)
                .collect(Collectors.toList());
        List<String> companyIdList = pageResult.getRecords().stream()
                .map(RiderTodayTaskDTO::getCompanyId)
                .collect(Collectors.toList());

        if (taskIdList.isEmpty()) {
            // 如果配送任务 ID 列表为空，则代表当前页没有配送任务，直接返回空数组即可
            return new PaginationResponseVO<>(pageResult.getTotal(), pageResult.getCurrent(), new ArrayList<>());
        }

        // 根据配送任务列表一次性查出所有店铺的订单数量
        List<TodayStoreOrderDTO> todayStoreOrders = deliveryTaskStoreMapper.queryTodayStoreOrder(taskIdList, companyIdList, deliveryDate);
        // 根据 taskId 分组
        Map<String, List<TodayStoreOrderDTO>> groupedByTaskId = todayStoreOrders.stream()
                .collect(Collectors.groupingBy(TodayStoreOrderDTO::getTaskId));

        List<RiderTodayTaskVO> records = pageResult.getRecords()
                .stream()
                .map(todayTask -> {
                    // 根据配送任务 ID 获取店铺及订单数量
                    List<TodayStoreOrderDTO> storeOrders = groupedByTaskId.getOrDefault(todayTask.getTaskId(), new ArrayList<>());
                    // 由于不同的配送任务可能会在相同的店铺取餐，导致查询出来的店铺订单数量重复，因此需要去重
                    // 根据配送任务 ID 及其对应的用餐时段 mealType 即可查询出在对应店铺中没有重复的订单数量
                    List<TodayStoreOrderDTO> storeOrderList = storeOrders.stream()
                            .filter(dto -> dto.getMealType().equals(todayTask.getMealType()))
                            .collect(Collectors.toList());
                    // 构建返回给前端的数据
                    return buildRiderTodayTaskVO(todayTask, storeOrderList);
                }).collect(Collectors.toList());

        return new PaginationResponseVO<>(pageResult.getTotal(), pageResult.getCurrent(), records);
    }

    private String getCurrentDate() {
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return currentDate.format(formatter);
    }

    private RiderTodayTaskVO buildRiderTodayTaskVO(RiderTodayTaskDTO todayTask, List<TodayStoreOrderDTO> storeOrders) {
        RiderTodayTaskVO vo = new RiderTodayTaskVO();
        vo.setTaskId(todayTask.getTaskId());
        vo.setTaskStatus(todayTask.getTaskStatus());
        vo.setCompanyId(todayTask.getCompanyId());
        vo.setCompanyName(todayTask.getCompanyName());
        vo.setDeliveryAddress(todayTask.getDeliveryAddress());
        vo.setDeliveryStartTime(todayTask.getDeliveryStartTime());

        int total = 0;
        List<StoreOrderVO> storeOrderVOList = new ArrayList<>();
        for (TodayStoreOrderDTO storeOrder : storeOrders) {
            StoreOrderVO storeOrderVO = new StoreOrderVO();
            storeOrderVO.setStoreId(storeOrder.getStoreId());
            storeOrderVO.setStoreName(storeOrder.getStoreName());
            storeOrderVO.setCount(storeOrder.getOrderCount());
            storeOrderVO.setStatus(storeOrder.getPickUpStatus());

            total += storeOrder.getOrderCount();
            storeOrderVOList.add(storeOrderVO);
        }
        vo.setTotalCount(total);
        vo.setStoreOrders(storeOrderVOList);

        vo.setMealTypeEn(todayTask.getMealType());
        vo.setMealType(MealTypeEnum.getMealTypeEnumByNameEn(todayTask.getMealType()).getMealTypeCn());
        // 同一批配送的订单，订单所属日期一定是相同的
        String dateFlag = getCurrentDate();
        if (!storeOrders.isEmpty()) {
            // 如果订单列表不为空，则以订单列表中第一个订单的订单日期为准
            dateFlag = storeOrders.get(0).getDateFlag();
        }
        vo.setDeliveryDate(dateFlag);
        return vo;
    }


    public StoreOrderDetailVO queryOrdersDetailByTaskIdStoreId(String taskId, String storeId) {
        Store store = storeMapper.selectById(storeId);
        if (store == null) {
            throw new IllegalArgumentException("ID 为 " + storeId + " 的店铺不存在");
        }

        CompanyIdWithMealTypeDTO companyIdWithMealType = deliveryTaskMapper.queryCompanyIdByTaskId(taskId);
        if (companyIdWithMealType == null) {
            throw new IllegalArgumentException("ID 为 " + taskId + " 的配送任务不存在");
        }

        String companyId = companyIdWithMealType.getCompanyId();
        String mealType = companyIdWithMealType.getMealType();
        String dateFlag = getCurrentDate();
        // 根据公司 ID、店铺 ID、用餐时段、订单所属日期查询订单详情中的数据
        List<TodayTaskOrderDetailDTO> todayTaskOrderDetailList = orderDetailMapper.queryOrderDetailByCompanyIdAndStoreId(companyId, storeId, mealType, dateFlag);
        List<TodayTaskOrderDetailVO> orderDetailList = todayTaskOrderDetailList.stream()
                .map(this::buildTodayTaskOrderDetailVO)
                .collect(Collectors.toList());

        StoreOrderDetailVO vo = new StoreOrderDetailVO();
        vo.setStoreId(storeId);
        vo.setStoreName(store.getName());
        vo.setOrderList(orderDetailList);

        return vo;
    }

    private TodayTaskOrderDetailVO buildTodayTaskOrderDetailVO(TodayTaskOrderDetailDTO dto) {
        TodayTaskOrderDetailVO vo = new TodayTaskOrderDetailVO();
        vo.setOrderDetailId(dto.getOrderDetailId());
        vo.setUsername(dto.getUsername());
        vo.setPhone(dto.getPhone());
        vo.setFoodImage(dto.getFoodImage());
        vo.setFoodName(dto.getFoodName());
        vo.setQuantity(dto.getQuantity());

        String lockerInfo = dto.getLockerInfo();
        if (StringUtils.hasText(lockerInfo)) {
            DeliverBoxApiParamVO deliverBoxApiParamVO = JSONObject.parseObject(lockerInfo, DeliverBoxApiParamVO.class);
            vo.setDeliveryLockerCab(deliverBoxApiParamVO.getCab());
            vo.setDeliveryLockerCol(deliverBoxApiParamVO.getCol());
            vo.setDeliveryLockerBoxNo(dto.getLockerBoxNo());
        }

        return vo;
    }


    public void confirmOrdersFetched(String taskId, String storeId) {
        DeliveryTaskStore deliveryTaskStore = new DeliveryTaskStore();
        // 将取餐状态修改为 2（已取餐）
        deliveryTaskStore.setPickUpStatus(2);

        LambdaUpdateWrapper<DeliveryTaskStore> updateWrapper = new LambdaUpdateWrapper<DeliveryTaskStore>()
                .eq(DeliveryTaskStore::getTaskId, taskId)
                .eq(DeliveryTaskStore::getStoreId, storeId);
        int updateCount = deliveryTaskStoreMapper.update(deliveryTaskStore, updateWrapper);
        if (updateCount != 1) {
            throw new ModifyFailureException("取餐状态修改失败");
        }
    }


    @Transactional(rollbackFor = {ModifyFailureException.class})
    public void confirmOrdersDelivered(String taskId) {
        DeliveryTask savedDeliveryTask = deliveryTaskMapper.selectById(taskId);
        if (savedDeliveryTask == null) {
            throw new IllegalArgumentException("ID 为 " + taskId + " 的配送任务不存在");
        }

        DeliveryTask deliveryTask = new DeliveryTask();
        deliveryTask.setId(taskId);
        // 将配送状态修改为 2（已完成）
        deliveryTask.setDeliveryStatus(2);
        int updateCount = deliveryTaskMapper.updateById(deliveryTask);
        if (updateCount != 1) {
            // 配送状态修改失败时，触发回滚
            throw new ModifyFailureException("配送状态修改失败");
        }

        // 将配送任务中所有店铺的取餐状态修改为 2（已取餐）
        DeliveryTaskStore deliveryTaskStore = new DeliveryTaskStore();
        deliveryTaskStore.setPickUpStatus(2);
        LambdaUpdateWrapper<DeliveryTaskStore> updateWrapper = new LambdaUpdateWrapper<DeliveryTaskStore>()
                .eq(DeliveryTaskStore::getTaskId, taskId);
        int updateNum = deliveryTaskStoreMapper.update(deliveryTaskStore, updateWrapper);
        if (updateNum == 0) {
            // 取餐状态修改失败时，触发回滚
            throw new ModifyFailureException("取餐状态修改失败");
        }
    }


    public TodayTaskBriefVO queryTodayTaskBrief(String riderId) {
        // 获取今天的日期，yyyy-MM-dd 格式
        String deliveryDate = getCurrentDate();
        LambdaQueryWrapper<DeliveryTask> queryWrapper = new LambdaQueryWrapper<DeliveryTask>()
                .eq(DeliveryTask::getRiderId, riderId)
                .eq(DeliveryTask::getDeliveryDate, deliveryDate)
                .eq(DeliveryTask::getDelFlag, false);
        // TODO: 此 SQL 下 MySQL 返回的无效列太多，可优化
        List<DeliveryTask> deliveryTasks = deliveryTaskMapper.selectList(queryWrapper);
        int totalCount = deliveryTasks.size();
        long incompleteCount = deliveryTasks.stream()
                .filter(task -> task.getDeliveryStatus().equals(1))
                .count();
        TodayTaskBriefVO vo = new TodayTaskBriefVO();
        vo.setTotalTaskCount(totalCount);
        vo.setIncompleteTaskCount((int) incompleteCount);

        return vo;
    }
}
